package com.nti56.springboot.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.nti56.springboot.cache.BaseDataCache;
import com.nti56.springboot.mapper.tmsmapper.MachRunTimeMapper;
import com.nti56.springboot.model.DictItem;
import com.nti56.springboot.model.MachInfo;
import com.nti56.springboot.model.MachProduct;
import com.nti56.springboot.model.MachRunTime;
import com.nti56.springboot.model.ProdMstr;
import com.nti56.springboot.utils.Constant;
import com.nti56.springboot.utils.DateUtil;
import com.nti56.springboot.utils.DictConstant;
import com.nti56.springboot.utils.ParamUtil;
import com.nti56.springboot.utils.ParamUtil.Param;

@Service
public class MachRunTimeService {
	
	private static final Logger logger = LoggerFactory.getLogger(MachRunTimeService.class);

	@Autowired
    private MachProductService machProductService;  
	@Autowired
	private MachRunTimeMapper machRunTimeMapper;
	@Autowired
    private BaseDataCache baseDataCache;
	
	public MachRunTime getById(String mpId) {
		return this.machRunTimeMapper.getById(mpId);
	}
	
	public List<MachRunTime> findAll(Map params) {
		return machRunTimeMapper.findAll(params);
	}
	
	public void insertMachRunTime(List<MachRunTime> mrtList,String shift) {
		for(MachRunTime mrt : mrtList) {
			Param param = ParamUtil.setParam("machNum", mrt.getMachNum())
								   .setParam("proDate", mrt.getProDate())
								   .setParam("shift", shift);
			Long cnt = this.machRunTimeMapper.countByMap(param);
			mrt.setShift(shift);
			if(cnt > 0) {
				this.machRunTimeMapper.update(mrt);
			}else {
				this.machRunTimeMapper.insert(mrt);
			}
		}
	}
	
	/**
	 * 计算 4中状态的时间之和
	 * @param proDate  生产日期
	 */
	public void calculate(Date proDate) {
		String workDay = DateUtil.format(proDate, DateUtil.DATE_PATTERN);
		String tableName = this.createViewName(workDay);
		String shift ="";
		try {
			if(this.shiftAmPm(proDate, new Date())) {
				shift = Constant.CNC_X_AM;
			}else {
				shift = Constant.CNC_Y_PM;
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		Param param = ParamUtil.setParam("tableName", tableName);
		if(Constant.CNC_X_AM.equals(shift)) {
			param.setParam("fromTime", workDay+" "+Constant.CNC_SHIFT_AM)
				 .setParam("toTime", workDay+" "+Constant.CNC_SHIFT_PM);
		}else {
			param.setParam("fromTime", workDay+" "+Constant.CNC_SHIFT_PM);
		}
							
		List<MachProduct> mpList = machProductService.findAll(param); 
		if(!CollectionUtils.isEmpty(mpList)) {
			Map<String, List<MachProduct>> collect = mpList.stream().collect(Collectors.groupingBy(MachProduct::getMachNum));
	    	List<MachRunTime> mrtList = new ArrayList<MachRunTime>();
	    	for(String machNum:collect.keySet()) {
	    		List<MachProduct> groupByMpList = collect.get(machNum);
	    		Double sumRun = 0d;
	    		Double sumStand = 0d;
	    		Double sumAlarm = 0d;
	    		Double sumOffLine = 0d;
	    		for(int i=0;i<groupByMpList.size();i++) {
	    			double dis = 0d;
	    			if(i==0) {
	    				//第一条数据之前的时间和早班上班时间 之间的  都算离线状态时间
	    				String dtStr = "";
	    				if(Constant.CNC_X_AM.equals(shift)) {
	    					dtStr = workDay+" "+Constant.CNC_SHIFT_AM;
	    				}else {
	    					dtStr = workDay+" "+Constant.CNC_SHIFT_PM;
	    				}   				
	    				Date toDate = null;
						try {
	    					toDate = DateUtil.parseDate(dtStr, DateUtil.DATETIME_PATTERN);
						} catch (Exception e) {
						}
	    				dis = DateUtil.getDistanceSecond(groupByMpList.get(i).getTime(), toDate);
	    				sumOffLine +=dis;
	    			}else {
	    				dis = DateUtil.getDistanceSecond(groupByMpList.get(i).getTime(), groupByMpList.get(i-1).getTime());
	    			}
	    			if(Constant.CNC_MACH_STATUS_RUNNING.contains(groupByMpList.get(i).getStatus())) {
	    				sumRun +=dis;
	    			}
	    			if(Constant.CNC_MACH_STATUS_STANDBY.contains(groupByMpList.get(i).getStatus())) {
	    				sumStand +=dis;
	    			}
	    			if(Constant.CNC_MACH_STATUS_ALARM.contains(groupByMpList.get(i).getStatus())) {
	    				sumAlarm +=dis;
	    			}
	    			if(Constant.CNC_MACH_STATUS_OFFLINE.contains(groupByMpList.get(i).getStatus())) {
	    				sumOffLine +=dis;
	    			}
	    		}
	    		MachRunTime mrt = new MachRunTime();
	    		mrt.setProDate(proDate);
	    		mrt.setMachNum(machNum);
	    		mrt.setRunTime(Math.abs(sumRun));
	    		mrt.setAlarm(Math.abs(sumAlarm));
	    		mrt.setOffLine(Math.abs(sumOffLine));
	    		mrt.setStandBy(Math.abs(sumStand));
	    		mrtList.add(mrt);
	    	}
			//插入数据
	    	this.insertMachRunTime(mrtList,shift);
		}
	}
	
	/**
	   * 判断当前时间
	 * @param now
	 * @return
	 * @throws Exception 
	 */
	private boolean shiftAmPm(Date proDate,Date nowTime) throws Exception {
		String workDay = DateUtil.format(proDate, DateUtil.DATE_PATTERN);
		String fromDate =workDay+" "+Constant.CNC_SHIFT_AM;
		String toDate =workDay+" "+Constant.CNC_SHIFT_PM;
		Date startTime = DateUtil.parseDate(fromDate, DateUtil.DATETIME_PATTERN);
		Date endTime = DateUtil.parseDate(toDate, DateUtil.DATETIME_PATTERN);
		return DateUtil.isEffectiveDate(nowTime, startTime, endTime);
	}
	
	private String createViewName(String workDay) {
		String viewName = "`"+workDay+"_view`";
		return viewName;
	}
	
	/**
	 * 堆叠图，标题
	 * @return
	 */
	public List<String> getBarLegend(){
		List<DictItem> items = baseDataCache.getDictItemsByDictCode(DictConstant.DICT_MACH_RUN_STATE);
		List<String> list = new ArrayList<String>();
		for(DictItem di : items) {
			list.add(di.getItemText());
		}
		return list;
	}
	
	/**
	 * 根据机台信息获取 YAxisData
	 * @return
	 */
	public List<String> getYAxisData(List<MachInfo> machInfoList,String proDate,String shift){
		//目标产量信息
		
		List<String> list = new ArrayList<String>();
		for(MachInfo machInfo : machInfoList) {
			Param param = ParamUtil.setParam("proDate", proDate)
								   .setParam("shift", shift)
								   .setParam("machNum", machInfo.getMachNum());
			List<ProdMstr> targetProList = this.machProductService.getTargetProductList(param);
			if(!CollectionUtils.isEmpty(targetProList)) {
				ProdMstr pm = targetProList.get(0);
				list.add(machInfo.getMachNum()+" "+pm.getItemNo()+" "+pm.getStaffId());
			}else {
				list.add(machInfo.getMachNum()+" ");
			}
		}
		return list;
	}
}
